package com.siyoumi.component.api.jj;

import com.siyoumi.component.XBean;
import com.siyoumi.component.api.jj.robot.RobotAbstract;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.config.SysConfig;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.util.*;
import com.siyoumi.validator.XValidator;
import lombok.extern.slf4j.Slf4j;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JJ {
    static private JJ ins;

    private RobotAbstract robot;

    static public JJ getIns() {
        DingtalkRobot robot = SysConfig.getIns().getDingtalkRobot();
        if (robot == null) {
            XValidator.err(EnumSys.ENV_ERR.getR("未配置钉钉机械人参数"));
        }
        return getIns(robot);
    }

    static public JJ getIns(RobotType type) {
        String server = SysConfig.getIns().getEnv();

        String classPath = XStr.concat("com.siyoumi.component.api.jj.robot.", type.getType(), XStr.toUpperCase1(server));
        log.info("classPath: {}", classPath);
        Class<RobotAbstract> classType = XBean.getClassType(classPath);
        if (classType == null) {
            log.info("不存在拿默认");
            classPath = XStr.concat("com.siyoumi.component.api.jj.robot.", type.getType());
            log.info("classPath: {}", classPath);
            classType = XBean.getClassType(classPath);
        }

        return getIns(classType);
    }

    static public JJ getIns(RobotAbstract robot) {
        if (ins == null) {
            ins = new JJ();
        }
        ins.setRobot(robot);

        return ins;
    }

    static public JJ getIns(Class<?> class_r) {
        RobotAbstract robot = XBean.newIns((Class<RobotAbstract>) class_r);

        return getIns(robot);
    }

    /**
     * 加粗并换行
     */
    static public String txtBold(String s) {
        return XStr.concat(" **", s, "** \n\n");
    }

    /**
     * 斜体并换行
     */
    static public String txtItalic(String s) {
        return XStr.concat(" *", s, "* \n\n");
    }

    public void setRobot(RobotAbstract robot) {
        this.robot = robot;
    }

    /**
     * 对外发送方法
     *
     * @param msg    内容
     * @param url    链接
     * @param at_all true：@所有人
     * @return 返回发送结果
     */
    public XReturn send(String msg, String url, Boolean at_all) {
        StringBuilder sb = new StringBuilder();
        if (XStr.hasAnyText(url)) {
            sb.append(XStr.concat("*", url, "*\n\n"));
        }

        //服务器
        String server = SysConfig.getIns().getEnv();
        sb.append(XStr.concat("**[", server, "]**"));
        //x
        String x = XHttpContext.getX(false);
        if (XStr.hasAnyText(x)) {
            sb.append(XStr.concat("-[", x, "]"));
        }
        sb.append("\n\n");
        //时间
        sb.append(XStr.concat(XDate.toDateTimeString(), "\n\n"));
        //内容
        sb.append(XStr.concat(msg, "\n\n"));

        return sendApiMarkdown(XStr.maxLen(msg, 33), sb.toString(), at_all);
    }

    /**
     * 发markdown
     *
     * @param title  标题
     * @param text   内容
     * @param at_all true：@所有人
     * @return 返回发送结果
     */
    public XReturn sendApiMarkdown(String title, String text, Boolean at_all) {
        Map<String, Object> post_data = new HashMap<String, Object>();
        post_data.put("msgtype", "markdown");
        //内容
        Map<String, Object> markdown = new HashMap<String, Object>();
        markdown.put("title", title);
        markdown.put("text", text);
        post_data.put("markdown", markdown);
        //是否@所有人
        Map<String, Object> at = new HashMap<String, Object>();
        at.put("isAtAll", at_all);
        post_data.put("at", at);
        //post_data.put("atMobiles", at); //@某些人

        return sendApi(post_data);
    }

    /**
     * 调用接口
     *
     * @param post_data post参数
     * @return 请求结果
     */
    private XReturn sendApi(Map<String, Object> post_data) {
        Long timestamp = XDate.toMs();
        String sign = getSign(timestamp);

        Map<String, String> data = new HashMap<String, String>();
        data.put("timestamp", timestamp.toString());
        data.put("sign", sign);
        String query = XStr.queryFromMap(data, null, false);

        XReturn r;
        try {
            String url = XStr.concat(this.robot.getAccessToken(), "&", query);
            XLog.info(this.getClass(), "url:", url);
            XLog.info(this.getClass(), post_data);

            XHttpClient client = XHttpClient.getInstance();
            String returnStr = client.postJson(url, null, post_data);
            XLog.info(this.getClass(), returnStr);
            r = XJson.parseObject(returnStr, XReturn.class);
        } catch (Exception ex) {
            XLog.error(this.getClass(), ex.getMessage());
            r = XReturn.getR(123456, ex.getMessage());
        }

        return r;
    }


    /**
     * 生成签名
     *
     * @param timestamp 时间
     * @return 签名
     */
    private String getSign(Long timestamp) {
        String sign = "";
        try {
            String string1 = timestamp + "\n" + this.robot.getSecret();
            byte[] sign_hmac = XStr.hmacSHA256(string1, this.robot.getSecret());
            sign = URLEncoder.encode(XStr.base64Enc(sign_hmac), StandardCharsets.UTF_8);

            XLog.debug(this.getClass(), string1);
            XLog.debug(this.getClass(), sign_hmac);
            XLog.debug(this.getClass(), sign);
        } catch (Exception ex) {
            XLog.error(this.getClass(), ex.getMessage());
        }

        return sign;
    }
}
